import { useModel } from '@@/exports';
import { ActionType, FormInstance } from '@ant-design/pro-components';
import { useThrottle } from 'ahooks';
import { message } from 'antd';
import { useEffect, useMemo, useRef, useState } from 'react';

export type FlowAction = 'add' | 'edit' | 'view' | 'remove' | undefined;

interface ActionInfo {
  /** 当 Modal 打开时, 一般用于修改操作加载最新数据 */
  onModalOpen?: (values: Record<string, any>) => Promise<Record<string, any>>;

  /** 编辑完数据, 点击提交时调用 */
  onActionCall: (values: Record<string, any>) => Promise<Record<string, any>>;

  /** onActionCall 成功后的回调 */
  onActionSuccess?: (result: Record<string, any>) => void;
  /** onActionCall 失败后的回调 */
  onActionError?: (e: any) => void;
}

interface ActionControlProps {
  /** 新增操作 */
  addAction?: ActionInfo;
  /** 编辑操作 */
  editAction?: ActionInfo;
  /** 删除操作 */
  removeAction?: ActionInfo;
  /** 查看操作 */
  viewAction?: ActionInfo;
  /** 额外的操作 */
  extraActionMap?: {
    [key: string]: ActionInfo;
  };
}

export type UseActionControlReturnType = ReturnType<typeof useActionControl>;

/**
 * 使用 ProTable 的编辑表单
 */
const useActionControl = (props: ActionControlProps) => {
  const tableActionRef = useRef<ActionType>();
  const tableFormRef = useRef<FormInstance>();

  const editModalFormRef = useRef<FormInstance>();
  const { getActiveTab, updateTab, getHeaderTabState } = useModel('global');

  /** state 定义当前的操作 */
  const [action, setAction] = useState<FlowAction>(undefined);
  /** state 定义初始化的数据 */
  const [initData, setInitData] = useState<any>({});

  const isCreateOrUpdate = action === 'add' || action === 'edit';

  const [_loading, setLoading] = useState<boolean>(false);

  /** 定义一个防抖的 loading */
  const loading = useThrottle<boolean>(_loading, { wait: 200 });

  /** 打开新增Modal */
  const openAddModal = (initData?: any) => {
    setInitData({ ...initData });
    setAction('add');
    editModalFormRef.current?.setFieldsValue({ ...initData });
  };

  /** 打开修改Modal */
  const openUpdateModalAsync = async (initData?: any) => {
    // 设置初始化数据
    setInitData({ ...initData });
    setAction('edit');
    if (props.editAction?.onModalOpen) {
      try {
        setLoading(true);
        const formInitData = await props.editAction?.onModalOpen(initData);
        editModalFormRef.current?.setFieldsValue({ ...formInitData });
      } catch (e) {
      } finally {
        setLoading(false);
      }
    } else {
      editModalFormRef.current?.setFieldsValue({ ...initData });
    }
  };
  const openUpdateModal = (initData: any) => {
    openUpdateModalAsync(initData).then(() => {});
  };

  const openViewModal: (initData: any) => void = async (initData: any) => {
    setInitData(initData);
    setAction('view');
    if (props.viewAction?.onModalOpen) {
      try {
        setLoading(true);
        const formInitData = await props.viewAction?.onModalOpen(initData);
        editModalFormRef.current?.setFieldsValue({ ...formInitData });
      } catch (e) {
      } finally {
        setLoading(false);
      }
    } else {
      editModalFormRef.current?.setFieldsValue({ ...initData });
    }
  };

  /** 关闭Modal */
  const onCancel = () => {
    setAction(undefined);
    setInitData({});
  };

  const handleCreateAction = async (values: any) => {
    if (props.addAction) {
      try {
        setLoading(true);
        const result = await props.addAction.onActionCall(values);
        message.success('操作成功');
        tableActionRef.current?.reload();
        props.addAction.onActionSuccess?.(result);
        onCancel();
      } catch (e) {
        props.addAction.onActionError?.(e);
      } finally {
        setLoading(false);
      }
    }
  };

  const handleUpdateAction = async (values: any) => {
    if (props.editAction) {
      try {
        setLoading(true);
        const result = await props.editAction.onActionCall(values);
        message.success('操作成功');
        tableActionRef.current?.reload();
        props.editAction.onActionSuccess?.(result);
        onCancel();
      } catch (e) {
        props.editAction.onActionError?.(e);
      } finally {
        setLoading(false);
      }
    }
  };

  const handleRemoveAction = async (values: any) => {
    if (props.removeAction) {
      try {
        setLoading(true);
        const result = await props.removeAction.onActionCall(values);
        message.success('操作成功');
        tableActionRef.current?.reload();
        props.removeAction.onActionSuccess?.(result);
        onCancel();
      } catch (e) {
        props.removeAction.onActionError?.(e);
      } finally {
        setLoading(false);
      }
    }
  };

  const handleExtraAction = async (values: any) => {
    const actionExecutor = props.extraActionMap?.action;
    if (actionExecutor) {
      try {
        setLoading(true);
        const result = await actionExecutor?.onActionCall?.(values);
        actionExecutor.onActionSuccess?.(result);
        onCancel();
      } catch (e) {
        actionExecutor.onActionError?.(e);
      } finally {
        setLoading(false);
      }
    }
  };

  /** 处理提交操作, 这里只能处理常规的 create/update/delete 复杂的需要自己手动实现 */
  const onSubmit: (values: any) => Promise<void> = async (values: any) => {
    if (action === 'add') {
      return await handleCreateAction(values);
    } else if (action === 'edit') {
      return await handleUpdateAction(values);
    } else if (action === 'remove') {
      return await handleRemoveAction(values);
    } else {
      return await handleExtraAction(values);
    }
  };

  /** 处理删除操作 */

  /** 获取缓存的查询条件 */
  const queryParams = useMemo(() => {
    const activeTab = getActiveTab();
    return activeTab?.queryParams;
  }, [getHeaderTabState().headerTabsActiveKey]);

  /** 更新缓存的查询条件 */
  const updateQueryParams = (queryParams: any) => {
    const activeTab = getActiveTab();
    updateTab({
      ...activeTab,
      queryParams,
    });
  };

  /** 缓存的查询条件 填充到 表格查询表单 */
  const fillQueryParamsToTableForm = () => {
    tableFormRef.current?.setFieldsValue(getActiveTab()?.queryParams);
  };

  const reloadTableData = () => {
    tableActionRef.current?.reload();
  };

  const wrapLoading = async (action: () => Promise<any>) => {
    setLoading(true);
    let result: any;
    try {
      result = await action();
    } catch (e) {
    } finally {
      setLoading(false);
    }
    return result;
  };

  useEffect(() => {
    // 每次加载的时候 填充查询条件到表单
    fillQueryParamsToTableForm();
  }, []);

  return {
    table: {
      actionRef: tableActionRef,
      formRef: tableFormRef,
      params: getActiveTab()?.queryParams,
      onSubmit: (params: any) => updateQueryParams(params),
    },
    editModal: {
      loading: loading,
      action: action,
      readonly: action === 'view',
      initData: initData,
      onCancel: onCancel,
      onSubmit: onSubmit,
      editModalOpen: action !== undefined,
      editModalFormRef: editModalFormRef,
    },
    queryParams: {
      value: queryParams,
      update: updateQueryParams,
      refill: fillQueryParamsToTableForm,
    },

    actions: {
      openAddModal,
      openUpdateModal,
      /** 打开只读表单 */
      openViewModal,
      handleExtraAction,
      handleRemoveAction,
      reloadTableData,
    },
    loading: {
      value: loading,
      begin: () => setLoading(true),
      end: () => setLoading(false),
      wrap: wrapLoading,
    },
    isCreateOrUpdate,
  };
};

export default useActionControl;
